package com.steel.yfmall.cloud.assistant.view.impl;

import com.alibaba.fastjson.JSONObject;
import com.steel.yfmall.cloud.assistant.utils.zg.ZgViewUtil;
import com.steel.yfmall.cloud.assistant.view.GoodsTypeBeanService;
import com.steel.yfmall.cloud.assistant.zg.ZgSOService;
import com.steel.yfmall.cloud.assistant.dto.zg.SynZgResult;
import com.steel.yfmall.cloud.assistant.dto.zg.ZgSOResultBean;
import com.steel.yfmall.cloud.assistant.dto.zg.ZgViewBean;
import com.steel.yfmall.cloud.assistant.po.view.GoodsTypeBean;
import com.steel.yfmall.cloud.assistant.po.view.GoodsTypeBeanExample;
import com.steel.yfmall.cloud.assistant.po.view.GoodsTypeBeanExample.Criteria;
import com.steel.yfmall.cloud.assistant.view.mapper.GoodsTypeBeanMapper;
import com.steel.yfmall.cloud.components.utils.base.APIMsgBean;
import com.steel.yfmall.cloud.components.utils.base.ResponseCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author luo deng ren
 * @date 2020/11/9 20:48
 */
@Service
@Slf4j
public class GoodsTypeBeanServiceImpl implements GoodsTypeBeanService {

    @Resource
    GoodsTypeBeanMapper goodsTypeBeanMapper;

    @Resource
    ZgSOService zgSOService;

    /**
     * 同步中冠产品大类、形态信息业务信息
     *
     * @param zgViewBean
     * @return 结果
     */
    @Override
    public APIMsgBean synchronizationZgGoodsTypeBean(ZgViewBean zgViewBean) {
        APIMsgBean serviceDataBean = new APIMsgBean();
        //默认失败
        serviceDataBean.setSoaStateBean(ResponseCode.buildEnumErrorSOAStateBean("数据同步失败"));
        //参数校验
        String msg = checkData(zgViewBean);
        if (!StringUtils.isBlank(msg)) {
            serviceDataBean.setSoaStateBean(ResponseCode.buildEnumErrorSOAStateBean(msg));
            return serviceDataBean;
        }
        SynZgResult synZgResult = new SynZgResult();
        //同步计时开始
        long beginTime = System.currentTimeMillis();
        //查询tp01产品大类、形态信息请求中冠
        ZgSOResultBean viewData = zgSOService.getViewData(zgViewBean);
        //同步计时结束
        long endTime = System.currentTimeMillis();
        long costTime = (endTime - beginTime);
        //请求中冠成功后
        if ("Y".equals(viewData.getIsSuccess())) {
            List<GoodsTypeBean> goodsTypeBeans = null;
            try {
                goodsTypeBeans = JSONObject.parseArray(viewData.getData(), GoodsTypeBean.class);
            } catch (Exception e) {
                serviceDataBean.setSoaStateBean(ResponseCode.buildEnumErrorSOAStateBean("产品大类、形态信息数据同步解析出错"));
                log.error("产品大类、形态信息数据同步解析出错，错误信息：", e);
            }
            //检查数据库是否有重复,过滤掉重复信息并设置创建、更新、版本信息
            goodsTypeBeans = checkDataBase(goodsTypeBeans);
            if (!CollectionUtils.isEmpty(goodsTypeBeans)) {
                //批量新增
                int i = goodsTypeBeanMapper.batchInsertByList(goodsTypeBeans);
                if (i > 0) {
                    //设置同步所用时间
                    synZgResult.setSynTime(String.valueOf(costTime));
                    //设置同步条数
                    synZgResult.setCountNum(i);
                    //设置同步状态
                    synZgResult.setState(true);
                    serviceDataBean.setSoaStateBean(ResponseCode.buildEnumSuccessSOAStateBean("数据同步成功"));
                    serviceDataBean.setData(synZgResult);
                    //日志记录
                    log.info("产品大类、形态信息数据同步成功，本次同步" + i + "条数据,耗时" + costTime + "毫秒");
                }
            } else {
                log.info("无数据同步");
                serviceDataBean.setSoaStateBean(ResponseCode.buildEnumErrorSOAStateBean("无数据同步"));
            }
        } else {
            serviceDataBean.setSoaStateBean(ResponseCode.buildEnumErrorSOAStateBean(viewData.getMsg()));
        }
        //递归同步
        try {
            //起始页
            int startPage = Integer.parseInt(zgViewBean.getPageNum());
            //判断是否还有数据
            if (startPage < viewData.getZgpageData().getPages()) {
                startPage++;
                zgViewBean.setPageNum(String.valueOf(startPage));
                synchronizationZgGoodsTypeBean(zgViewBean);
            }
        } catch (Exception e) {
            serviceDataBean.setSoaStateBean(ResponseCode.buildEnumErrorSOAStateBean("产品大类、形态信息数据递归同步出错"));
            log.error("产品大类、形态信息数据递归同步出错，错误信息：", e);
        }
        return serviceDataBean;
    }

    /**
     * 检查数据库中数据是否存在，将不存在的数据返回，过滤掉重复的数据
     *
     * @param goodsTypeBeans 需要检查的数据
     * @return List<PostalCodeBean> 不重复的数据
     */
    private List<GoodsTypeBean> checkDataBase(List<GoodsTypeBean> goodsTypeBeans) {
        if (CollectionUtils.isEmpty(goodsTypeBeans)) {
            return null;
        }
        GoodsTypeBeanExample goodsTypeBeanExample = new GoodsTypeBeanExample();
        Criteria criteria = goodsTypeBeanExample.createCriteria();
        //提取产品形态编码去库中做数据比较，如果重复则判定为重复数据。
        Map<String, GoodsTypeBean> goodsTypeBeanMap = new HashMap<>();
        for (GoodsTypeBean goodsTypeBean : goodsTypeBeans) {
            goodsTypeBeanMap.put(goodsTypeBean.getProdTypeNo(), goodsTypeBean);
        }
        //查询数据库是否有重复数据
        Set<String> keys = goodsTypeBeanMap.keySet();
        List<String> keyList = new ArrayList<>(keys);
        criteria.andProdTypeNoIn(keyList);
        List<GoodsTypeBean> dbGoodsTypeBean = goodsTypeBeanMapper.selectByExample(goodsTypeBeanExample);
        List<GoodsTypeBean> oldGoodsTypeBean = new ArrayList<>();
        //比较是否用重复的数据
        for (GoodsTypeBean goodsTypeBean : dbGoodsTypeBean) {
            String newProdTypeNo = goodsTypeBean.getProdTypeNo();
            if (goodsTypeBeanMap.containsKey(newProdTypeNo)) {
                //重复的数据
                oldGoodsTypeBean.add(goodsTypeBeanMap.get(newProdTypeNo));
                //删除重复数据
                goodsTypeBeanMap.remove(newProdTypeNo);
            }
        }
        //不重复的数据视为新数据
        goodsTypeBeans = new ArrayList<>(goodsTypeBeanMap.values());
        for (int i = 0; i < goodsTypeBeans.size(); i++) {
            goodsTypeBeans.get(i).setCreateTime(new Date());
            goodsTypeBeans.get(i).setUpdateTime(new Date());
            goodsTypeBeans.get(i).setVersionInt(0);
        }
        //当有重复数据是执行同步
        if (!CollectionUtils.isEmpty(oldGoodsTypeBean)) {
            goodsTypeBeanMap.clear();
            for (GoodsTypeBean goodsTypeBean : oldGoodsTypeBean) {
                goodsTypeBeanMap.put(goodsTypeBean.getProdTypeNo(), goodsTypeBean);
            }
            List<GoodsTypeBean> postalCodeBeans1 = equalsDataChange(goodsTypeBeanMap);
            if (!CollectionUtils.isEmpty(postalCodeBeans1)) {
                AsynchronousUpDate asynchronousUpDate = new AsynchronousUpDate(postalCodeBeans1);
                new Thread(asynchronousUpDate).start();
            }
        }
        //返回不重复的数据
        return goodsTypeBeans;
    }

    /**
     * @param oldGoodsTypeBeanMap 重复的数据
     * @return List<PostalCodeBean> 重复且有差异的信息
     * @Description 校验比较返回重复且有差异的的信息
     */
    private List<GoodsTypeBean> equalsDataChange(Map<String, GoodsTypeBean> oldGoodsTypeBeanMap) {
        //如果对象为空就直接结束
        if (oldGoodsTypeBeanMap.isEmpty()) {
            return null;
        }
        //条件
        GoodsTypeBeanExample goodsTypeBeanExample = new GoodsTypeBeanExample();
        Criteria criteria = goodsTypeBeanExample.createCriteria();
        //将产品形态编码作为条件
        Set<String> strings = oldGoodsTypeBeanMap.keySet();
        criteria.andProdTypeNoIn(new ArrayList<>(strings));
        //查询出重复的数据用于细致比对
        List<GoodsTypeBean> dbGoodsTypeBean = goodsTypeBeanMapper.selectByExample(goodsTypeBeanExample);
        //用来存储重复且有差异的数据
        List<GoodsTypeBean> goodsTypeBeanList = new ArrayList<>();
        //用数据库中的数据和同步过来的数据进行比较
        for (GoodsTypeBean goodsTypeBean : dbGoodsTypeBean) {
            String prodTypeNo = goodsTypeBean.getProdTypeNo();
            //如果存在相同的产品形态编码
            if (oldGoodsTypeBeanMap.containsKey(prodTypeNo)) {
                GoodsTypeBean goodsTypeBeanForMap = oldGoodsTypeBeanMap.get(prodTypeNo);
                //当产品大类编码 产品大类中文名称 产品形态编码 产品形态中文名称 数据存在差异时判定为差异数据
                if (!goodsTypeBeanForMap.getProdClassChin().equals(goodsTypeBean.getProdClassChin())
                        || !goodsTypeBeanForMap.getProdTypeNo().equals(goodsTypeBean.getProdTypeNo())
                        || !goodsTypeBeanForMap.getProdTypeChin().equals(goodsTypeBean.getProdTypeChin())
                ) {
                    goodsTypeBeanForMap.setId(goodsTypeBean.getId());
                    goodsTypeBeanForMap.setUpdateTime(new Date());
                    goodsTypeBeanForMap.setVersionInt(goodsTypeBean.getVersionInt() + 1);
                    goodsTypeBeanList.add(goodsTypeBeanForMap);
                }
            }
        }
        return goodsTypeBeanList;
    }

    /**
     * 线程异步修改重复的数
     */
    private class AsynchronousUpDate implements Runnable {
        List<GoodsTypeBean> oldGoodsTypeBean;

        public AsynchronousUpDate(List<GoodsTypeBean> oldGoodsTypeBean) {
            this.oldGoodsTypeBean = oldGoodsTypeBean;
        }

        @Override
        public void run() {
            //判断是否存在有差异数据，如果有就修改
            try {
                if (!CollectionUtils.isEmpty(oldGoodsTypeBean)) {
                    //记录总需改数据
                    int i = 0;
                    long beginTime = System.currentTimeMillis();
                    for (GoodsTypeBean goodsTypeBean : oldGoodsTypeBean) {
                        i += goodsTypeBeanMapper.updateByPrimaryKeySelective(goodsTypeBean);
                    }
                    long endTime = System.currentTimeMillis();
                    long costTime = (endTime - beginTime);
                    log.info("异步修改产品大类,形态信息同步差异信息成功，本次修改" + i + "条数据，耗时" + costTime + "毫秒");
                }
            } catch (Exception e) {
                log.error("同步后的差异数据修改失败，错误原因：", e);
            }
        }
    }


    /**
     * sql拼接
     *
     * @param criteria      sql拼接
     * @param goodsTypeBean 参数
     */
    private void getSearchData(Criteria criteria, GoodsTypeBean goodsTypeBean) {
        // ID
        if (goodsTypeBean.getId() != null && goodsTypeBean.getId() > 0) {
            criteria.andIdEqualTo(goodsTypeBean.getId());
        }
        // 产品大类编码
        if (StringUtils.isNotBlank(goodsTypeBean.getProdClassNo())) {
            criteria.andProdClassNoEqualTo(goodsTypeBean.getProdClassNo());
        }
        //产品大类中文名称
        if (StringUtils.isNotBlank(goodsTypeBean.getProdClassChin())) {
            criteria.andProdClassChinEqualTo(goodsTypeBean.getProdClassChin());
        }
        //产品形态编码
        if (StringUtils.isNotBlank(goodsTypeBean.getProdTypeNo())) {
            criteria.andProdTypeNoEqualTo(goodsTypeBean.getProdTypeNo());
        }
        //产品型态中文名称
        if (StringUtils.isNotBlank(goodsTypeBean.getProdTypeChin())) {
            criteria.andProdTypeChinEqualTo(goodsTypeBean.getProdTypeChin());
        }
        //创建时间
        if (goodsTypeBean.getCreateTime() != null) {
            criteria.andCreateTimeEqualTo(goodsTypeBean.getCreateTime());
        }
        //版本号
        if (goodsTypeBean.getVersionInt() != null && goodsTypeBean.getVersionInt() > 0) {
            criteria.andVersionIntEqualTo(goodsTypeBean.getVersionInt());
        }
        //修改时间
        if (goodsTypeBean.getUpdateTime() != null) {
            criteria.andUpdateTimeEqualTo(goodsTypeBean.getUpdateTime());
        }
    }

    /**
     * 中冠视图请求的参数校验
     *
     * @param zgViewBean 视图名称
     * @return 校验结果
     */
    private String checkData(ZgViewBean zgViewBean) {
        String msg = "";
        if (!StringUtils.isNotBlank(zgViewBean.getMethod())) {
            msg += "请求方法不能为空";
        }
        if (!StringUtils.isNotBlank(zgViewBean.getViewId())) {
            msg += "请求的视图不能为空";
        }
        if (!StringUtils.isNotBlank(zgViewBean.getPageNum())) {
            msg += "请求的页码不能为空";
        }
        return msg;
    }
}
